package com.punai.config.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.punai.common.exception.base.BaseException;
import com.punai.common.utils.PageUtils;
import com.punai.config.domain.ConfigMaterialCategory;
import com.punai.config.domain.ConfigMaterialInfo;
import com.punai.config.domain.vo.ConfigMaterialCategoryVo;
import com.punai.config.domain.vo.ConfigMaterialInfoVo;
import com.punai.config.mapper.ConfigMaterialCategoryMapper;
import com.punai.config.mapper.ConfigMaterialInfoMapper;
import com.punai.config.service.ConfigMaterialPLCService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class ConfigMaterialPLCServiceImpl implements ConfigMaterialPLCService {
    @Autowired
    private ConfigMaterialCategoryMapper materialCategoryMapper;
    @Autowired
    private ConfigMaterialInfoMapper materialInfoMapper;
    @Override
    public List<ConfigMaterialCategoryVo> getAllAddress(String type) {
        return materialCategoryMapper.selectAllAddress(type);
    }

    @Override
    public ConfigMaterialCategoryVo saveCategory(ConfigMaterialCategoryVo vo) {
        String dataType = vo.getDataType();
        if(StrUtil.equals("0", dataType)){
            ConfigMaterialCategory findByAddress = materialCategoryMapper.selectOne(Wrappers.<ConfigMaterialCategory>lambdaQuery()
                    .eq(ConfigMaterialCategory::getAddress, vo.getAddress())
                    .eq(ConfigMaterialCategory::getPid, '0')
            );
            if(findByAddress!=null) throw new BaseException("地区重复");
            //添加地区
            ConfigMaterialCategory one = new ConfigMaterialCategory();
            one.setPid("0");
            one.setType(vo.getType());
            one.setDataType(dataType);
            one.setDataStatus(vo.getDataStatus());
            one.setAddress(vo.getAddress());
            Integer maxOrderNum = materialCategoryMapper.selectMaxOrderNum(one.getPid());
            one.setOrderNum(maxOrderNum + 1);
            materialCategoryMapper.insert(one);
        }
        if (StrUtil.equals("1", dataType)) {
            ConfigMaterialCategory findByCode = materialCategoryMapper.selectOne(Wrappers.<ConfigMaterialCategory>lambdaQuery()
                    .eq(ConfigMaterialCategory::getCode,vo.getCode())
            );
            //添加分类
            if(StrUtil.isEmpty(vo.getId())){
                if(findByCode!=null) throw new BaseException("编码重复");
                ConfigMaterialCategory P = materialCategoryMapper.selectById(vo.getPid());
                ConfigMaterialCategory one = new ConfigMaterialCategory();
                one.setPid(vo.getPid());
                one.setType(vo.getType());
                one.setDataType(dataType);
                one.setDataStatus(vo.getDataStatus());
                one.setAddress(P==null?"":P.getAddress());
                one.setCode(vo.getCode());
                one.setName(vo.getName());
                Integer maxOrderNum = materialCategoryMapper.selectMaxOrderNum(one.getPid());
                one.setOrderNum(maxOrderNum + 1);
                materialCategoryMapper.insert(one);
            }else{
                if (findByCode!=null && !StrUtil.equals(findByCode.getId(),vo.getId())) throw new BaseException("编码重复");
                ConfigMaterialCategory one = materialCategoryMapper.selectById(vo.getId());
                one.setCode(vo.getCode());
                one.setName(vo.getName());
                materialCategoryMapper.updateById(one);
            }
        }
        return vo;
    }

    @Override
    public List<ConfigMaterialCategoryVo> getTreeCategory(String pid, String type) {
        List<ConfigMaterialCategoryVo> res = new ArrayList<>();
        List<ConfigMaterialCategoryVo> root = materialCategoryMapper.selectAllByTypeAndPid(type, pid);
        for (ConfigMaterialCategoryVo vo : root) {
            res.add(vo);
            if (vo.getId().equals(pid)) continue;//过滤自己，避免递归循环
            getTreeChild(vo,res);
        }
        return res;
    }

    @Override
    public List<ConfigMaterialCategoryVo> getAllCategory(String pid, String type) {
        List<ConfigMaterialCategoryVo> res = new ArrayList<>();
        List<ConfigMaterialCategoryVo> root = materialCategoryMapper.selectAllByTypeAndPid(type, pid);
        for (ConfigMaterialCategoryVo vo : root) {
            res.add(vo);
            if(vo.getId().equals(pid)) continue;//过滤自己，避免递归循环
            getChild(vo, res);
        }
        return res;
    }
    @Override
    public ConfigMaterialCategoryVo getCategoryInfo(String id) {
        ConfigMaterialCategory one = materialCategoryMapper.selectById(id);
        ConfigMaterialCategoryVo res = new ConfigMaterialCategoryVo();
        BeanUtil.copyProperties(one,res);
        ConfigMaterialCategory p = materialCategoryMapper.selectById(res.getPid());
        res.setIsSelPid(res.getPid());
        if(p != null && StrUtil.equals(p.getPid(),"0")){
            res.setIsSelPid(null);
        }
        return res;
    }

    @Override
    public ConfigMaterialCategory removeCategory(String id) {
        ConfigMaterialCategory one = materialCategoryMapper.selectById(id);

        List<ConfigMaterialInfoVo> allInfo = this.getAllInfo(new ConfigMaterialInfoVo(){{setCategoryId(id);setType(one.getType());}});
        allInfo.forEach(v->this.removeMaterialInfo(new ConfigMaterialInfoVo(){{
            setId(v.getId());
        }}));


        one.setDataStatus("1");
        materialCategoryMapper.updateById(one);
        return one;
    }

    @Override
    public List<ConfigMaterialInfoVo> getAllInfo(ConfigMaterialInfoVo vo) {
        String categoryId = vo.getCategoryId();
        String type = vo.getType();
        String code = vo.getCode();
        String name = vo.getName();
        PageUtils.startPage();
        List<ConfigMaterialCategoryVo> allCategory = this.getAllCategory(categoryId, type);
        return materialInfoMapper.selectAllByTypeAndCategoryIdsAndCodeAndName(
                type,
                allCategory.stream().map(ConfigMaterialCategoryVo::getId).collect(Collectors.toList()),
                code,
                name
        );
    }

    @Override
    public ConfigMaterialInfoVo saveMaterialInfo(ConfigMaterialInfoVo vo) {
        String id = vo.getId();
        ConfigMaterialInfo selectOneByCode = materialInfoMapper.selectOne(Wrappers.<ConfigMaterialInfo>lambdaQuery().eq(ConfigMaterialInfo::getCode, vo.getCode()));
        if(StrUtil.isEmpty(id)){
            if(selectOneByCode!=null) throw new BaseException("编码重复");
            String categoryId = vo.getCategoryId();
            ConfigMaterialCategory category = materialCategoryMapper.selectById(categoryId);
            String addressId = "";
            if(StrUtil.equals("zf_0", category.getType())){
                ConfigMaterialCategory address = materialCategoryMapper.selectOne(Wrappers.<ConfigMaterialCategory>lambdaQuery()
                        .eq(ConfigMaterialCategory::getAddress, category.getAddress())
                        .eq(ConfigMaterialCategory::getPid, "0")
                );
                addressId = address.getId();
            }

            ConfigMaterialInfo one = new ConfigMaterialInfo();
            one.setCategoryId(categoryId);
            one.setAddressId(addressId);
            one.setType(vo.getType());
            one.setCode(vo.getCode());
            one.setName(vo.getName());
            one.setSpec(vo.getSpec());
            one.setUnit(vo.getUnit());
            one.setDataStatus(vo.getDataStatus());
            Integer maxOrderNum = materialInfoMapper.selectMaxOrderNum(one.getCategoryId());
            one.setOrderNum(maxOrderNum + 1);
            materialInfoMapper.insert(one);
        }else{
            ConfigMaterialInfo one = materialInfoMapper.selectById(id);
            if (selectOneByCode != null && !selectOneByCode.getId().equals(one.getId())) throw new BaseException("编码重复");
            one.setCode(vo.getCode());
            one.setName(vo.getName());
            one.setSpec(vo.getSpec());
            one.setUnit(vo.getUnit());
            materialInfoMapper.updateById(one);
        }
        return null;
    }

    @Override
    public ConfigMaterialInfo removeMaterialInfo(ConfigMaterialInfoVo vo) {
        ConfigMaterialInfo one = materialInfoMapper.selectById(vo.getId());
        one.setDataStatus("1");
        materialInfoMapper.updateById(one);
        return one;
    }

    @Override
    public ConfigMaterialInfo getMaterialInfo(String id) {
        return materialInfoMapper.selectById(id);
    }

    private void getTreeChild(ConfigMaterialCategoryVo Pvo, List<ConfigMaterialCategoryVo> res){
        List<ConfigMaterialCategoryVo> root = materialCategoryMapper.selectAllByTypeAndPid(Pvo.getType(), Pvo.getId());
        for (ConfigMaterialCategoryVo vo : root) {
            if (vo.getId().equals(Pvo.getId())) continue;//过滤自己，避免递归循环
            Pvo.getChildren().add(vo);
            getTreeChild(vo, res);
        }
    }

    private void getChild(ConfigMaterialCategoryVo Pvo, List<ConfigMaterialCategoryVo> res) {
        List<ConfigMaterialCategoryVo> root = materialCategoryMapper.selectAllByTypeAndPid(Pvo.getType(), Pvo.getId());
        for (ConfigMaterialCategoryVo vo : root) {
            if (vo.getId().equals(Pvo.getId())) continue;//过滤自己，避免递归循环
            res.add(vo);
            getChild(vo, res);
        }
    }
}
